package com.zjxny.jobs;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import com.zjxny.service.AccountService;
import com.zjxny.service.WxCpZjService;

import cn.hutool.core.map.MapBuilder;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import xyz.erupt.core.annotation.EruptHandlerNaming;
import xyz.erupt.job.handler.EruptJobHandler;

@Slf4j
@Service
@EruptHandlerNaming("刷新TOKEN会话")
public class RefreshTokenJob implements EruptJobHandler {
    @Resource
    AccountService accountService;
    
    @Resource
    JdbcTemplate jdbcTemplate;
    
    @Resource
	WxCpZjService wxCpZjService;
    
    List<String>  filterHeader = Arrays.asList("X-Cache","X-Frame-Options","Transfer-Encoding","Server","Content-Encoding","Connection","Vary","Content-Type","Date");
    
    @Override
    public String exec(String code, String param) {

        List<Map<String,Object>> list =accountService.getAccountWithCookies();
        log.info("refresh.token.invoked list.size={}",list.size());

        if(list.isEmpty()){
            return null;
        }

        for(Map<String,Object> map:list){
            Long id = (Long) map.get("id");
            String cookies= (String) map.get("cookies");
            String domain = (String) map.get("domain");
            String simpleTitle = (String) map.get("simple_title");
            String toUser = (String) map.get("notify_cp_name");

            if(StrUtil.isNotBlank(cookies)){
                refresh(id,toUser,simpleTitle,cookies,domain);
            }
        }
        return null;
    }

    private void refresh(Long id,String toUser,String simpleTitle,String cookieStr,String domain){
    	//https://yn.122.gov.cn/user/m/userinfo/vehs

        JSONArray arr = JSONUtil.parseArray(cookieStr);
        List<String> cookieArr = arr.stream().map(s -> {
            JSON t = (JSON) s;
            return String.format("%s=%s", t.getByPath("name", String.class), t.getByPath("value", String.class));
        }).collect(Collectors.toList());

        String cookies=StrUtil.join("; ", cookieArr);

        //https://gd.122.gov.cn/views/memfyy/index.html
        String url = String.format("https://%s/user/m/userinfo/vehs", domain);
        String referer = String.format("https://%s/views/memfyy/vehinfo.html?index=7", domain);
        
        MapBuilder<String, Object> builder = MapUtil.builder(new HashMap<String, Object>())
				.put("page", "1")
				.put("size", "10")
				.put("status", "null")//根据状态来查询
				.put("hphm", "")
				.put("hpzl", "52");

        HttpRequest request = HttpRequest.post(url).header("Referer", referer);
        request.header("Cookie",cookies);
        request.header("User-Agent","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36");

        HttpResponse response = request.form(builder.build()).execute();
        
        System.err.println(response.body());
        
        if(response.getStatus()==302) {
        	String sql = "update account_info set cookies=null,is_valid=0 where id="+id;
        	int affectNum = jdbcTemplate.update(sql);
        	log.info("clear.cookie id={},affectNum={}",id,affectNum);
        	
//        	发送通知
        	if(StrUtil.isNotBlank(toUser)) {				
				wxCpZjService.sendNotifyMessage(toUser,String.format("%s会话过期,请及时处理!", simpleTitle));
			}
        	return ;
        }
        
        
        //response
        Map<String,List<String>> headers = response.headers().entrySet().stream().filter(s->!filterHeader.contains(s.getKey())).collect(Collectors.toMap(s->s.getKey(), s->s.getValue()));
        
        if(headers!=null && !headers.isEmpty()) {
        	log.info("RefreshToken.response {} header={}",simpleTitle, JSONUtil.toJsonStr(headers));
        }
        
        if(null!=headers && headers.containsKey("Set-Cookie")) {
        	//写入新的COOKIE
        	List<Map<String, String>> cookieList = Arrays.stream(cookieStr.split(";"))
            		.filter(s->s.contains("="))
            	    .map(s -> {
            	        Map<String, String> map = new HashMap<>();
            	        String[] parts = s.split("=");
            	        map.put(parts[0].trim(), parts[1].trim());
            	        return map;
            	    })
            	    .collect(Collectors.toList());
        	String cookie = JSONUtil.toJsonStr(cookieList);
        	String sql = "update account_info set cookies='"+cookie+"' where id="+id;
        	int affectNum = jdbcTemplate.update(sql);
        	
        	log.info("update.cookie id={},affectNum={},cookie={}",id,affectNum,cookie);
        }
        log.info("refresh.token.invoked. company={},http.status={}",simpleTitle,response.getStatus());
    }
    
    public static void main(String[] args) {

    	String cookieStr = "JSESSIONID-L=b387dae6-8c58-42b7-ba49-8b8dba1989e7; Path=/; HttpOnly";

    	List<Map<String, String>> cookieList = Arrays.stream(cookieStr.split(";"))
        		.filter(s->s.contains("="))
        	    .map(s -> {
        	        Map<String, String> map = new HashMap<>();
        	        String[] parts = s.split("=");
        	        map.put(parts[0].trim(), parts[1].trim());
        	        return map;
        	    })
        	    .collect(Collectors.toList());
    	
    	System.err.println(JSONUtil.toJsonPrettyStr(cookieList));

	}
}